package com.tgy.admin.Service.impl;

import cn.dev33.satoken.secure.BCrypt;
import cn.dev33.satoken.stp.SaLoginConfig;
import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.JSONObject;
import com.tgy.admin.Service.LoginService;
import com.tgy.admin.Service.MenuService;
import com.tgy.ao.LoginAo;
import com.tgy.constant.Constant;
import com.tgy.constant.RedisKey;
import com.tgy.core.service.SysAdminService;
import com.tgy.enums.ResponseStatusEnum;
import com.tgy.enums.YesOrNo;
import com.tgy.exception.GlobalException;
import com.tgy.pojo.SysAdmin;
import com.tgy.result.GraceJSONResult;
import com.tgy.util.RedisUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;

/**
 * @author tianguiyin
 * @version 1.0
 * @date 2022/6/20 21:48
 *
 * 登陆注册业务实现
 */
@Service
public class LoginServiceImpl implements LoginService {

    @Resource
    private SysAdminService sysAdminService;

    @Resource
    private MenuService menuService;

    @Resource
    private RedisUtils redis;

    @Value("${tgy.maxErrorNumber}")
    private String maxErrorNumber;
    @Value("${sa-token.timeout}")
    private Long timeout;

    /**
     * 登录
     */
    @Override
    public String login(LoginAo ao) {
        // 判断验证码
        // 获取用户信息
        SysAdmin admin = new SysAdmin();
        admin.setAccount(ao.getUsername());
        admin.setStatus(YesOrNo.YES.type);
        List<SysAdmin> sysAdmins = sysAdminService.queryList(admin);
        if (CollectionUtil.isEmpty(sysAdmins)){
            GlobalException.display(ResponseStatusEnum.LOGIN_USER_NOTFOND);
        }
        SysAdmin sysAdmin = sysAdmins.get(0);
        // 判断账号状态
        if (Constant.AVAILABLE_FALSE.equals(sysAdmin.getStatus())){
            GlobalException.display(ResponseStatusEnum.LOGIN_USER_ERRORSTATUS);
        }
        // 判断错误次数
        boolean b = redis.keyIsExist(RedisKey.LOGIN_WRONG_NUMBER+":"+sysAdmin.getId());
        if (b && Integer.valueOf(redis.get(RedisKey.LOGIN_WRONG_NUMBER+":"+sysAdmin.getId())) >= Integer.valueOf(maxErrorNumber)){
            GlobalException.display(ResponseStatusEnum.LOGIN_USER_ERRORNUMBER);
        }
        // 判断密码
        // System.out.println("拉拉："+BCrypt.hashpw("admin"));
        if (!BCrypt.checkpw(ao.getPassword(), sysAdmin.getPassword())){
            if (b){
                redis.increment(RedisKey.LOGIN_WRONG_NUMBER+":"+sysAdmin.getId(),1L);
            }else {
                redis.set(RedisKey.LOGIN_WRONG_NUMBER+":"+sysAdmin.getId(),Constant.STRING_ONE);
            }
            GlobalException.display(ResponseStatusEnum.LOGIN_PASSWORD_ERROR);
        }
        // 登录
        // StpUtil.login(sysAdmin.getId());
        // 向token中添加信息
        StpUtil.login(sysAdmin.getId(), SaLoginConfig
                .setExtra("account", sysAdmin.getAccount())
                .setExtra("status", sysAdmin.getStatus()));
        // 删除错误次数
        redis.del(RedisKey.LOGIN_WRONG_NUMBER+":"+sysAdmin.getId());

        // 缓存用户信息
        redis.set(RedisKey.LOGIN_USER_INFO+":"+sysAdmin.getId(), JSONObject.toJSONString(sysAdmin),timeout);

        // 获取当前人的菜单、角色、权限等信息
        menuService.getMenuAndRoleAndPermission(sysAdmin.getId());

        // 返回token
        return StpUtil.getTokenValue();
    }

    @Override
    public GraceJSONResult logout() {
        try {
            String loginId = StpUtil.getLoginId().toString();
            // 删除缓存
            redis.del(RedisKey.LOGIN_USER_INFO+":"+loginId);
            redis.del(RedisKey.LOGIN_USER_MENU+":"+loginId);
            redis.del(RedisKey.LOGIN_USER_ROLE+":"+loginId);
            redis.del(RedisKey.LOGIN_USER_PERMISSION+":"+loginId);
            // satoken退出
            StpUtil.logout();
            return GraceJSONResult.ok("注销成功");
        }catch (Exception e){
            e.printStackTrace();
            return GraceJSONResult.error();
        }
    }
}
